package com.dmz.etc.server.netty.server;

import com.dmz.etc.server.config.EnvConfig;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Laptop
 */
@Slf4j
public class NettyServer implements Runnable {

    public void start () {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childOption(ChannelOption.TCP_NODELAY, true)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        // 添加对byte数组的编解码，netty提供了很多编解码器，你们可以根据需要选择
                        //pipeline.addLast(new DmzDecoder());
                        pipeline.addLast(new ByteArrayDecoder());
                        pipeline.addLast(new ByteArrayEncoder());
                        // 设置读操作超时时间为5秒
                        pipeline.addLast(new ReadTimeoutHandler(30));
                        // 设置写操作超时时间为5秒
                        pipeline.addLast(new WriteTimeoutHandler(30));
                        // 设置读空闲超时时间为 60 秒
                        pipeline.addLast(new IdleStateHandler(30, 0, 0));
                        pipeline.addLast(new LengthFieldBasedFrameDecoder(65535, 0, 4, 0, 4));
                        // 添加上自己的处理器
                        ServerHandler serverHandler = new ServerHandler(workerGroup);
                        pipeline.addLast(serverHandler);
                    }
                });
        try {
            String port = EnvConfig.getProperty("dmz.server.netty.port");
            ChannelFuture f = bootstrap.bind(Integer.parseInt(port)).sync();
            log.info("netty server start success");
            f.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public void run() {
        this.start();
    }
}
